import { sessionGetItem } from './auth'
// index.ts
import axios from 'axios'
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'
import { message as antd_message } from 'antd'
import store from '@/store'
import { changeLoading } from '@/store/modules/user'
// 导出Request类，可以用来自定义传递配置来创建实例
export class Request {
  // axios 实例
  instance: AxiosInstance

  // 基础配置，url和超时时间
  baseConfig: AxiosRequestConfig = { baseURL: '', timeout: 10000 }

  constructor(config: AxiosRequestConfig) {
    // 使用axios.create创建axios实例
    this.instance = axios.create(Object.assign(this.baseConfig, config))

    this.instance.interceptors.request.use(
      (config: AxiosRequestConfig) => {
        // 开启loading
        store.dispatch(changeLoading(true))
        // 一般会请求拦截里面加token，用于后端的验证
        const token = sessionGetItem('token') as string
        if (token) {
          config.headers!.Authorization = token
        }

        return config
      },
      (err: AxiosError) => {
        // 请求错误，这里可以用全局提示框进行提示
        return Promise.reject(err)
      }
    )

    this.instance.interceptors.response.use(
      (res: AxiosResponse) => {
        // 直接返回res，当然你也可以只返回res.data
        // 系统如果有自定义code也可以在这里处理
        // 关闭loading
        store.dispatch(changeLoading(false))
        const { code, message } = res.data
        if (code === 200) {
          return res.data
        }
        antd_message.error(message)
        return Promise.reject(message)
      },
      (err: AxiosError) => {
        // 这里用来处理http常见错误，进行全局提示
        let message = ''
        if (err.response) {
          switch (err.response.status) {
            case 400:
              message = '请求错误(400)'
              break
            case 401:
              message = '未授权，请重新登录(401)'
              // 这里可以做清空storage并跳转到登录页的操作
              break
            case 403:
              message = '拒绝访问(403)'
              break
            case 404:
              message = '请求出错(404)'
              break
            case 408:
              message = '请求超时(408)'
              break
            case 500:
              message = '服务器错误(500)'
              break
            case 501:
              message = '服务未实现(501)'
              break
            case 502:
              message = '网络错误(502)'
              break
            case 503:
              message = '服务不可用(503)'
              break
            case 504:
              message = '网络超时(504)'
              break
            case 505:
              message = 'HTTP版本不受支持(505)'
              break
            default:
              message = `连接出错(${err.response.status})!`
          }
          antd_message.error(message)
          return Promise.reject(err.response)
        } else {
          antd_message.error('发生未知的错误')
          return Promise.reject('发生未知的错误')
        }
      }
    )
  }

  // 定义请求方法
  public request<T>(config: AxiosRequestConfig): Promise<Result<T>> {
    return this.instance.request(config)
  }

  public get<T>(url: string, config?: AxiosRequestConfig): Promise<Result<T>> {
    return this.instance.get(url, config)
  }

  public post<T>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<Result<T>> {
    return this.instance.post(url, data, config)
  }

  public put<T>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<Result<T>> {
    return this.instance.put(url, data, config)
  }

  public delete<T>(url: string, config?: AxiosRequestConfig): Promise<Result<T>> {
    return this.instance.delete(url, config)
  }
}
export const axiosApi = new Request({
  baseURL: '/api',
  timeout: 1000
})
